import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:path/path.dart' as path;
import 'dart:io' show Platform;
import 'package:flutter/foundation.dart' show kIsWeb;
import 'auth_service.dart';
import '../models/file_item.dart';
import '../models/api_response.dart';
import 'dart:typed_data';
import '../config/app_config.dart';
import 'package:flutter/foundation.dart' show debugPrint;
import 'api_service.dart';
import 'dart:async';

class FileService {
  // API服务器地址
  static String get baseUrl => AppConfig.apiServerUrl;

  // 创建广播流控制器，用于通知文件列表更新
  static final StreamController<void> _fileListUpdateController =
      StreamController<void>.broadcast();

  // 获取文件列表更新通知流
  static Stream<void> get fileListUpdateStream =>
      _fileListUpdateController.stream;

  // 发送文件列表更新通知
  static void notifyFileListUpdated() {
    _fileListUpdateController.add(null);
  }

  // 处理预览URL，移除阻碍预览的参数
  static String _processPreviewUrl(String url) {
    try {
      // 处理 Content-Type
      final contentType = _getContentTypeFromUrl(url);
      if (contentType != null) {
        // 替换或添加 response-content-type 参数
        final uri = Uri.parse(url);
        final queryParams = Map<String, String>.from(uri.queryParameters);
        queryParams['response-content-type'] = contentType;
        url = uri.replace(queryParameters: queryParams).toString();
      }

      debugPrint('预览URL (原始): $url');
      debugPrint('预览URL (处理后): $url');

      return url;
    } catch (e) {
      debugPrint('处理URL出错: $e');
      return url;
    }
  }

  // 根据文件扩展名获取正确的 Content-Type
  static String? _getContentTypeFromUrl(String url) {
    final uri = Uri.parse(url);
    final path = uri.path.toLowerCase();

    // 图片类型
    if (path.endsWith('.jpg') || path.endsWith('.jpeg')) return 'image/jpeg';
    if (path.endsWith('.png')) return 'image/png';
    if (path.endsWith('.gif')) return 'image/gif';
    if (path.endsWith('.webp')) return 'image/webp';
    if (path.endsWith('.svg')) return 'image/svg+xml';

    // 视频类型
    if (path.endsWith('.mp4')) return 'video/mp4';
    if (path.endsWith('.webm')) return 'video/webm';
    if (path.endsWith('.ogg')) return 'video/ogg';

    // 音频类型
    if (path.endsWith('.mp3')) return 'audio/mpeg';
    if (path.endsWith('.wav')) return 'audio/wav';
    if (path.endsWith('.flac')) return 'audio/flac';

    // 文档类型
    if (path.endsWith('.pdf')) return 'application/pdf';
    if (path.endsWith('.doc') || path.endsWith('.docx'))
      return 'application/msword';
    if (path.endsWith('.xls') || path.endsWith('.xlsx'))
      return 'application/vnd.ms-excel';
    if (path.endsWith('.ppt') || path.endsWith('.pptx'))
      return 'application/vnd.ms-powerpoint';

    return null;
  }

  // 处理文件名乱码问题
  static String sanitizeFileName(String fileName) {
    try {
      final bytes = utf8.encode(fileName);
      final decodedName = utf8.decode(bytes, allowMalformed: true);
      String sanitizedName = decodedName.replaceAll('\uFFFD', '_');

      if (sanitizedName.trim().isEmpty ||
          sanitizedName.replaceAll('_', '').isEmpty) {
        sanitizedName = '未命名文件';
      }

      return sanitizedName;
    } catch (e) {
      debugPrint('文件名清理错误: $e');
      return '未命名文件';
    }
  }

  // 上传文件
  static Future<ApiResponse<FileUploadResponse>> uploadFile(
    dynamic fileSource, {
    String? fileName,
    Map<String, String>? fields,
  }) async {
    return ApiService.uploadFile<FileUploadResponse>(
      '/upload',
      fileSource: fileSource,
      fileName: fileName,
      fields: fields,
      fromJson: (data) => FileUploadResponse.fromJson(data),
    );
  }

  // 获取文件列表
  static Future<ApiResponse<PaginatedData<FileItem>>> getFileList({
    int page = 1,
    int pageSize = 20,
    String? fileType,
    String? keyword,
    String? startTime,
    String? endTime,
    String? fileHash,
    bool isDeleted = false,
    int? directoryId,
  }) async {
    final userId = await AuthService.getUserId();
    if (userId == null) {
      throw Exception('用户未登录');
    }

    final queryParams = {
      'user_id': userId.toString(),
      'page': page.toString(),
      'page_size': pageSize.toString(),
      'is_delete': isDeleted.toString(),
      if (fileType != null) 'file_type': fileType,
      if (keyword != null) 'keyword': keyword,
      if (startTime != null) 'start_time': startTime,
      if (endTime != null) 'end_time': endTime,
      if (fileHash != null) 'file_hash': fileHash,
      if (directoryId != null) 'directory_id': directoryId.toString(),
    };

    return ApiService.get<PaginatedData<FileItem>>(
      '/files',
      queryParams: queryParams,
      fromJson:
          (data) => PaginatedData<FileItem>.fromJson(
            data as Map<String, dynamic>,
            (item) => FileItem.fromJson(item),
          ),
    );
  }

  // 获取已删除的文件列表
  static Future<List<FileItem>> getDeletedFiles({
    int page = 1,
    int pageSize = 100,
    String? fileType,
    String? keyword,
    String? startTime,
    String? endTime,
  }) async {
    debugPrint('FileService - getDeletedFiles - 开始获取已删除文件');
    try {
      final userId = await AuthService.getUserId();
      debugPrint('FileService - getDeletedFiles - 获取到用户ID: $userId');

      if (userId == null) {
        debugPrint('FileService - getDeletedFiles - 用户未登录');
        throw Exception('请先登录后再访问回收站');
      }

      final queryParams = {
        'user_id': userId.toString(),
        'is_delete': 'true',
        'page': page.toString(),
        'page_size': pageSize.toString(),
        if (fileType != null) 'file_type': fileType,
        if (keyword != null) 'keyword': keyword,
        if (startTime != null) 'start_time': startTime,
        if (endTime != null) 'end_time': endTime,
      };
      debugPrint('FileService - getDeletedFiles - 请求参数: $queryParams');

      final response = await ApiService.get<PaginatedData<FileItem>>(
        '/files',
        queryParams: queryParams,
        fromJson: (data) {
          debugPrint('FileService - getDeletedFiles - 开始解析响应数据');
          debugPrint('FileService - getDeletedFiles - 原始数据: $data');

          if (data == null) {
            debugPrint('FileService - getDeletedFiles - 服务器返回数据为空');
            throw Exception('服务器返回数据为空');
          }

          try {
            final paginatedData = PaginatedData<FileItem>.fromJson(
              data as Map<String, dynamic>,
              (item) {
                debugPrint('FileService - getDeletedFiles - 解析文件项: $item');
                return FileItem.fromJson(item as Map<String, dynamic>);
              },
            );
            debugPrint(
              'FileService - getDeletedFiles - 成功解析数据，文件数量: ${paginatedData.items.length}',
            );
            return paginatedData;
          } catch (e, stackTrace) {
            debugPrint('FileService - getDeletedFiles - 数据解析错误: $e');
            debugPrint('错误堆栈: $stackTrace');
            rethrow;
          }
        },
      );

      if (!response.isSuccess) {
        debugPrint(
          'FileService - getDeletedFiles - API请求失败: ${response.message}',
        );
        throw Exception(response.message);
      }

      if (response.data == null) {
        debugPrint('FileService - getDeletedFiles - API响应数据为空');
        return [];
      }

      debugPrint(
        'FileService - getDeletedFiles - 成功获取已删除文件列表，数量: ${response.data!.items.length}',
      );
      return response.data!.items;
    } catch (e, stackTrace) {
      debugPrint('FileService - getDeletedFiles - 发生错误: $e');
      debugPrint('错误堆栈: $stackTrace');
      rethrow;
    }
  }

  // 批量删除文件
  static Future<ApiResponse<BatchOperationResponse>> batchDeleteFiles(
    List<int> fileIds, {
    bool permanent = false,
  }) async {
    final userId = await AuthService.getUserId();
    if (userId == null) {
      throw Exception('用户未登录');
    }

    return ApiService.post<BatchOperationResponse>(
      '/files/batch-delete',
      queryParams: {'user_id': userId.toString()},
      body: {'file_ids': fileIds, 'permanent': permanent},
      fromJson: (data) => BatchOperationResponse.fromJson(data),
    );
  }

  // 批量删除目录和文件（新API）
  static Future<ApiResponse<BatchOperationResponse>> batchDeleteItems({
    List<int>? directoryIds,
    List<int>? fileIds,
    bool permanent = false,
    bool recursive = true,
  }) async {
    final userId = await AuthService.getUserId();
    if (userId == null) {
      throw Exception('用户未登录');
    }

    final Map<String, dynamic> body = {
      'permanent': permanent,
      'recursive': recursive,
    };

    if (directoryIds != null && directoryIds.isNotEmpty) {
      body['directory_ids'] = directoryIds;
    }

    if (fileIds != null && fileIds.isNotEmpty) {
      body['file_ids'] = fileIds;
    }

    return ApiService.post<BatchOperationResponse>(
      '/directories/batch-delete',
      queryParams: {'user_id': userId.toString()},
      body: body,
      fromJson: (data) => BatchOperationResponse.fromJson(data),
    );
  }

  // 批量恢复文件
  static Future<ApiResponse<BatchOperationResponse>> batchRestoreFiles(
    List<int> fileIds,
  ) async {
    final userId = await AuthService.getUserId();
    if (userId == null) {
      throw Exception('用户未登录');
    }

    return ApiService.post<BatchOperationResponse>(
      '/files/batch-restore',
      queryParams: {'user_id': userId.toString()},
      body: {'file_ids': fileIds},
      fromJson: (data) => BatchOperationResponse.fromJson(data),
    );
  }

  // 获取文件预览信息
  static Future<ApiResponse<FilePreviewResponse>> getFilePreview(
    int fileId, {
    bool forceRefresh = false,
  }) async {
    final queryParams =
        forceRefresh
            ? {'t': DateTime.now().millisecondsSinceEpoch.toString()}
            : null;

    return ApiService.get<FilePreviewResponse>(
      '/files/$fileId/preview',
      queryParams: queryParams,
      fromJson: (data) => FilePreviewResponse.fromJson(data),
      additionalHeaders: {
        'Cache-Control': 'no-cache, no-store, must-revalidate',
        'Pragma': 'no-cache',
        'Expires': '0',
      },
    );
  }

  // 获取文件下载链接
  static Future<ApiResponse<FileDownloadResponse>> getFileDownload(
    int fileId,
  ) async {
    return ApiService.get<FileDownloadResponse>(
      '/files/$fileId/download',
      fromJson: (data) => FileDownloadResponse.fromJson(data),
    );
  }

  // 格式化文件大小
  static String formatFileSize(int bytes) {
    if (bytes < 1024) return '$bytes B';
    if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(1)} KB';
    if (bytes < 1024 * 1024 * 1024)
      return '${(bytes / (1024 * 1024)).toStringAsFixed(1)} MB';
    return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(1)} GB';
  }

  // 检查文件是否为音频文件
  static bool isAudioFile(String? fileName, String? mimeType) {
    if (fileName == null && mimeType == null) return false;

    if (mimeType != null) {
      return mimeType.startsWith('audio/');
    }

    if (fileName != null) {
      final ext = fileName.split('.').last.toLowerCase();
      return [
        'mp3',
        'wav',
        'ogg',
        'flac',
        'aac',
        'm4a',
        'wma',
        'opus',
        'webm',
        '3gp',
      ].contains(ext);
    }

    return false;
  }

  // 判断文件是否可预览
  static bool isPreviewSupported(String fileType) {
    return true;
  }

  // 永久删除文件
  static Future<ApiResponse<BatchOperationResponse>> permanentlyDeleteFiles(
    List<int> fileIds,
  ) {
    return batchDeleteItems(fileIds: fileIds, permanent: true);
  }

  // 永久删除目录和文件
  static Future<ApiResponse<BatchOperationResponse>> permanentlyDeleteItems({
    List<int>? directoryIds,
    List<int>? fileIds,
  }) {
    return batchDeleteItems(
      directoryIds: directoryIds,
      fileIds: fileIds,
      permanent: true,
    );
  }
}
